﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;

namespace WFExtended.Framework.ServiceModel
{
    /// <summary>
    /// Service Model Helper
    /// </summary>
    public static class ServiceModelHelper
    {
        /// <summary>
        /// Gets the operations.
        /// </summary>
        /// <param name="serviceType">Type of the service.</param>
        /// <returns></returns>
        public static Dictionary<string, Tuple<MethodInfo, Dictionary<string, Type>>>  GetOperations(Type serviceType)
        {
            Dictionary<string, Tuple<MethodInfo, Dictionary<string, Type>>> operations =
                new Dictionary<string, Tuple<MethodInfo, Dictionary<string, Type>>>();

            foreach (MethodInfo currentMethod in serviceType.GetMethods())
            {
                OperationContractAttribute operationAttr =
                    currentMethod.GetCustomAttributes(typeof(OperationContractAttribute))
                    .FirstOrDefault() as OperationContractAttribute;

                if (operationAttr != null)
                {
                    if (String.IsNullOrEmpty(operationAttr.Name))
                        operationAttr.Name = currentMethod.Name;

                    Dictionary<string, Type> parameters = new Dictionary<string, Type>();

                    foreach (ParameterInfo currentParam in currentMethod.GetParameters())
                        parameters.Add(currentParam.Name, currentParam.ParameterType);

                    operations.Add(operationAttr.Name, new Tuple<MethodInfo,Dictionary<string,Type>>(currentMethod, parameters));
                }
            }

            return operations;
        }

        /// <summary>
        /// Gets the operation.
        /// </summary>
        /// <param name="serviceType">Type of the service.</param>
        /// <param name="operationName">Name of the operation.</param>
        /// <returns></returns>
        public static Tuple<MethodInfo, Dictionary<string, Type>> GetOperation(Type serviceType, string operationName)
        {
            return GetOperations(serviceType)
                .Where((O) => O.Key == operationName)
                .Select((KV) => KV.Value)
                .FirstOrDefault();
        }
    }
}
